import { ref, reactive, Ref, unref } from 'vue';
import { AxiosResponse } from 'axios';
import { Pagination } from '@/types/global';

interface GetParamsCb {
  form: any;
  activeKey: any;
  paginationData: Pagination;
}

type Api = (a?: any) => Promise<AxiosResponse<any, any>>;

interface UsePageParams {
  api?: Api | Ref<Api>;
  getParams?: (x?: GetParamsCb) => Record<string, any>;
  getInitParams?: () => Record<string, any>;
  getResetParams?: (x?: GetParamsCb) => Record<string, any>;
  afterReq?: (x: any) => any;
  pageSizeOptions?: number[];
  defaultPageSize?: number;
}

export default function usePage({
  api,
  getParams,
  getInitParams,
  afterReq,
  getResetParams,
  pageSizeOptions,
  defaultPageSize = 20,
}: UsePageParams) {
  let funParams: UsePageParams = {
    api,
    getParams,
    getInitParams,
    afterReq,
    getResetParams,
  };

  const makeInitParams = () => {
    if (funParams.getInitParams) {
      return funParams.getInitParams();
    }
    return {};
  };

  const formData = ref<Record<string, any>>(makeInitParams());

  const renderData = ref<any[]>([]);
  const loading = ref<boolean>(false);

  const pageSizeList = pageSizeOptions || [10, 20, 50, 100, 300];
  const pagination = reactive<Pagination>({
    total: 0,
    current: 1,
    pageSize: defaultPageSize || pageSizeList[0],
    showTotal: true,
    showPageSize: true,
    pageSizeOptions: pageSizeList,
  });

  const tabActiveKey = ref<any>('');

  const fetchData = (type: 'get' | 'reset' = 'get') => {
    if (!funParams.api) return;
    let addParams = {};

    if (type === 'reset') {
      const resetParams = funParams.getResetParams
        ? funParams.getResetParams({
            form: makeInitParams(),
            activeKey: tabActiveKey.value,
            paginationData: pagination,
          })
        : {};
      addParams = {
        ...resetParams,
      };
    }

    if (type !== 'reset' && funParams.getParams) {
      addParams = funParams.getParams({
        form: JSON.parse(JSON.stringify(formData.value)),
        activeKey: tabActiveKey.value,
        paginationData: pagination,
      });
    }

    const data = {
      page_size: pagination.pageSize,
      page_num: pagination.current,
      ...addParams,
    };

    loading.value = true;
    // eslint-disable-next-line no-underscore-dangle
    const _api = unref(funParams.api);
    _api(data)
      .then((res) => {
        let afterMakeData = res.data;

        if (funParams.afterReq) {
          afterMakeData = funParams.afterReq(res.data);
        }

        renderData.value = afterMakeData.rows.map((t: any, idx: number) => {
          return {
            ...t,
            no: idx + 1,
          };
        });
        pagination.total = afterMakeData.total;
      })
      .finally(() => {
        loading.value = false;
      });
  };

  const handleReset = () => {
    formData.value = makeInitParams();
    pagination.current = 1;
    fetchData();
  };

  const handleSearch = () => {
    pagination.current = 1;
    fetchData();
  };

  const onChangeTab = (value: any) => {
    tabActiveKey.value = value;
    handleSearch();
  };

  const onPageChange = (current: number) => {
    console.log('🚀 ~ onPageChange ~ current:', current);
    pagination.current = current;
    fetchData();
  };

  const onPageSizeChange = (pageSize: number) => {
    pagination.pageSize = pageSize;
    handleSearch();
  };

  const updateHooksParams = (obj: UsePageParams) => {
    funParams = {
      ...funParams,
      ...obj,
    };
  };

  return {
    renderData,
    loading,
    pagination,
    tabActiveKey,
    formData,
    fetchData,
    handleReset,
    handleSearch,
    onChangeTab,
    onPageChange,
    onPageSizeChange,
    updateHooksParams,
  };
}
